package com.wef.system.service.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Hibernate;

import com.gfa4j.exception.ValidateRuntimeException;
import com.gfa4j.hibernate.BaseObject;
import com.gfa4j.service.impl.BaseServiceImpl;
import com.wef.system.entity.MenuGroup;
import com.wef.system.entity.MenuItem;
import com.wef.system.entity.Module;
import com.wef.system.entity.Role;
import com.wef.system.entity.RoleMenuButton;
import com.wef.system.entity.RoleMenuItem;
import com.wef.system.entity.ViewButton;
import com.wef.system.entity.domain.MenuGroupDomain;
import com.wef.system.entity.domain.MenuItemDomain;
import com.wef.system.entity.domain.RoleDomain;
import com.wef.system.entity.domain.RoleMenuButtonDomain;
import com.wef.system.entity.domain.RoleMenuItemDomain;
import com.wef.system.entity.domain.ViewButtonDomain;
import com.wef.system.service.PrivilegeService;

@SuppressWarnings("unchecked")
public class PrivilegeServiceImpl extends BaseServiceImpl implements PrivilegeService {

	public Set<RoleMenuItem> loadRoleMenuItemByRoleId(String roleId) {
		Role role = (Role) super.load(Role.class, roleId);
		for (RoleMenuItem rmi : (Collection<RoleMenuItem>) role.getRoleMenuItems()) {
			Hibernate.initialize(rmi.getMenuItem());
			for (RoleMenuButton rmb : (Collection<RoleMenuButton>) rmi.getRoleMenuButtons()) {
				Hibernate.initialize(rmb.getViewButton());
			}
		}
		return role.getRoleMenuItems();
	}

	public Set<RoleMenuItem> saveRoleMenuWithButtons(String roleId, Set<RoleMenuItem> roleMenuItems) {
		List<Role> roleList = (List<Role>) super.findByProperty(Role.class, RoleDomain.roleId, roleId);
		if (roleList.size() == 0) {
			throw new ValidateRuntimeException(getMessage("alert.roleNotFound"));
		}
		Role role = roleList.get(0);
		List<RoleMenuItem> allRoleMenuItem = null;
		for (RoleMenuItem rmi : roleMenuItems) {
			Set<RoleMenuButton> roleMenuButtons = rmi.getRoleMenuButtons();
			rmi.setRoleMenuButtons(null);

			if (rmi.getRowStatus() == BaseObject.ROWSTATUS_ADDED) {
				rmi.setRole(role);
				rmi.setMenuItem((MenuItem) super.load(MenuItem.class, rmi.getMenuItemId()));
				super.saveObject(rmi);
			} else if (rmi.getRowStatus() == BaseObject.ROWSTATUS_DELETED) {
				allRoleMenuItem = (List<RoleMenuItem>) super.findByProperty(RoleMenuItem.class, RoleMenuItemDomain.role, role);
				for (RoleMenuItem armi : allRoleMenuItem) {
					if (armi.getMenuItem().getMenuItemId().equals(rmi.getMenuItemId())) {
						if (roleMenuButtons.size() > 0) {// 删除Item之前先删除Button
							delRoleMenuButton(roleMenuButtons, armi);
						}
						if (existRoleMenuButton(armi)) {
							throw new ValidateRuntimeException(getMessage("alert.needDelChildNodes"));
						}
						super.deleteObject(armi);
						break;
					}
				}
			}
			if (rmi.getRowStatus() != BaseObject.ROWSTATUS_DELETED) {
				if (roleMenuButtons.size() > 0) {
					allRoleMenuItem = (List<RoleMenuItem>) super.findByProperty(RoleMenuItem.class, RoleMenuItemDomain.role, role);
					for (RoleMenuItem armi : allRoleMenuItem) {
						if (armi.getMenuItem().getMenuItemId().equals(rmi.getMenuItemId())) {
							saveRoleMenuButton(roleMenuButtons, armi);
							break;
						}
					}
				}
			}
		}
		return null;
	}

	/**
	 * 更新菜单下的按钮
	 */
	private void saveRoleMenuButton(Set<RoleMenuButton> roleMenuButtons, RoleMenuItem roleMenuItem) {
		for (RoleMenuButton rmb : roleMenuButtons) {
			ViewButton vb = (ViewButton) super.load(ViewButton.class, rmb.getViewButtonId());
			if (rmb.getRowStatus() == BaseObject.ROWSTATUS_ADDED) {
				rmb.setRoleMenuItem(roleMenuItem);
				rmb.setRoleMenuItemId(roleMenuItem.getRoleMenuItemId());
				rmb.setViewButton(vb);
				super.saveObject(rmb);
			}
			if (rmb.getRowStatus() == BaseObject.ROWSTATUS_DELETED) {
				Map<String, String> params = new HashMap<String, String>();
				params.put(RoleMenuButtonDomain.roleMenuItemId, roleMenuItem.getRoleMenuItemId());
				params.put(RoleMenuButtonDomain.viewButtonId, vb.getViewButtonId());
				List<RoleMenuButton> dbRmbList = (List<RoleMenuButton>) super.findByProperty(RoleMenuButton.class, params);
				if (dbRmbList.size() > 0) {
					super.deleteObject(dbRmbList.get(0));
				}
			}
		}
	}

	/**
	 * 删除菜单下的按钮
	 */
	private void delRoleMenuButton(Set<RoleMenuButton> roleMenuButtons, RoleMenuItem roleMenuItem) {
		for (RoleMenuButton rmb : roleMenuButtons) {
			ViewButton vb = (ViewButton) super.load(ViewButton.class, rmb.getViewButtonId());
			if (rmb.getRowStatus() == BaseObject.ROWSTATUS_DELETED) {
				Map<String, String> params = new HashMap<String, String>();
				params.put(RoleMenuButtonDomain.roleMenuItemId, roleMenuItem.getRoleMenuItemId());
				params.put(RoleMenuButtonDomain.viewButtonId, vb.getViewButtonId());
				List<RoleMenuButton> dbRmbList = (List<RoleMenuButton>) super.findByProperty(RoleMenuButton.class, params);
				if (dbRmbList.size() > 0) {
					super.deleteObject(dbRmbList.get(0));
					roleMenuItem.getRoleMenuButtons().remove(dbRmbList.get(0));
				}
			}
		}
	}

	/**
	 * 判断是否存在子节点
	 * 
	 * @param roleMenuButtons
	 * @param roleMenuItem
	 */
	private boolean existRoleMenuButton(RoleMenuItem roleMenuItem) {
		Map<String, String> params = new HashMap<String, String>();
		params.put(RoleMenuButtonDomain.roleMenuItemId, roleMenuItem.getRoleMenuItemId());
		List<RoleMenuButton> dbRmbList = (List<RoleMenuButton>) super.findByProperty(RoleMenuButton.class, params);
		return dbRmbList != null && !dbRmbList.isEmpty() ? true : false;
	}

	public List<MenuGroup> loadMenuGroups(String moduleId) {
		Module module = (Module) super.load(Module.class, moduleId);
		return super.findByProperty(MenuGroup.class, MenuGroupDomain.module, module);
	}

	public List<MenuItem> loadMenuItems(String menuGroupId) {
		MenuGroup menuGroup = (MenuGroup) load(MenuGroup.class, menuGroupId);
		List<MenuItem> results = super.findByProperty(MenuItem.class, MenuItemDomain.menuGroup, menuGroup);
		return results;
	}

	public List<ViewButton> loadViewButtons(String menuItemId) {
		MenuItem menuItem = (MenuItem) load(MenuItem.class, menuItemId);
		return super.findByProperty(ViewButton.class, ViewButtonDomain.menuItem, menuItem);
	}
}
